<?php

/**
 * Subclass for representing a row from the 'user' table.
 *
 *
 *
 * @package lib.model
 */
class User extends BaseUser
{

	public function updateFromWebRequest(sfWebRequest $request){
		$fields = array_flip(UserPeer::getFieldNames(BasePeer::TYPE_FIELDNAME));
		unset($fields['id']);
		$params = $request->getParameterHolder()->getAll();
		$field_keys = array_keys($fields);
		$param_keys = array_keys($params);
		$matched_fields = count(array_intersect($field_keys,$param_keys));
		if($matched_fields){
			$this->fromArray($params,BasePeer::TYPE_FIELDNAME);
		}else{
			Throw new sfException("No fields to save");
		}

	}

	public function validateData(){
		return $this->getName()!='';
	}

	public function toJSONArray(){
		$data = parent::toArray(BasePeer::TYPE_FIELDNAME);
		return $data;
	}

	public function getOpposites($limit=10,$as_array=false){
		$c = UserPeer::getOppositesCriteria($this);
		$c->setLimit($limit);
		$opposites = OppositePeer::doSelectAsOpposites($c);
		if(!$as_array){
			return $opposites;
		}else{
			$ret=array();
			foreach($opposites as $opposite){
				$ret[]=$opposite->toJSONArray();
			}
			return $ret;
		}
		return $opposites;
	}

	public function getOppositesPager($page=1,$num_per_page=10){
		$c = UserPeer::getOppositesCriteria($this);
		//$opposites = OppositePeer::doSelectAsOpposites($c);
		$pager = new sfPropelPager('Opposite',$num_per_page);
		$pager->setCriteria($c);
		$pager->setPeerMethod('doSelectAsOpposites');
		$pager->setPage($page);
		$pager->init();
		return $pager;
	}


	public function getPerfectOpposites($limit=10,$as_array=false){
		$c = UserPeer::getPerfectOppositesCriteria($this);
		$c->setLimit($limit);
		$opposites = OppositePeer::doSelectAsPerfectOpposites($c);
		if(!$as_array){
			return $opposites;
		}else{
			$ret=array();
			foreach($opposites as $opposite){
				$ret[]=$opposite->toJSONArray();
			}
			return $ret;
		}
		return $opposites;
	}


	public function getReversedPerfectOpposites($limit=10,$as_array=false){
		$c = UserPeer::getReversedPerfectOppositesCriteria($this);
		$c->setLimit($limit);
		$reversed_opposites = UserPeer::doSelect($c);
		if(!$as_array){
			return $reversed_opposites;
		}else{
			$ret=array();
			foreach($reversed_opposites as $opposite){
				$ret[]=$reversed_opposites->toJSONArray();
			}
			return $ret;
		}
		return $reversed_opposites;
	}


	public function getOppositesIds($limit=10){
		$c = UserPeer::getOppositesCriteria($this);
		$c->setLimit($limit);
		$ids = array();
		/* var $rs MysqlResultSet */
		$rs = OppositePeer::doSelectRS($c);
		if($rs->getRecordCount()>0){
			while($rs->next()){
				$u = new User();
				$offset = $u->hydrate($rs);
				$score = $rs->getInt($offset);
				$num_answers = $rs->getInt($offset+1);
				$compared_with = $rs->getString($offset+2);
				$ret['ids'][]=$u->getId();
				$ret['oppositeness'][$u->getId()]=($score/$num_answers)*100;
			}
		}
		return $ids;
	}


	public function getPerfectOppositesIds($limit=5){
		/* @var $c Criteria */
		$c = UserPeer::getPerfectOppositesCriteria($this);
		$c->setLimit($limit);
		$ret = array();
		$ret['ids']=array();
		$ret['oppositeness']=array();
		/* var $rs MysqlResultSet */
		$rs = OppositePeer::doSelectRS($c);
		if($rs->getRecordCount()>0){
			while($rs->next()){
				$u = new User();
				$offset = $u->hydrate($rs);
				$score = $rs->getInt($offset);
				$num_answers = $rs->getInt($offset+1);
				$compared_with = $rs->getString($offset+2);
				$ret['ids'][]=$u->getId();
				$ret['oppositeness'][$u->getId()]=($score/$num_answers)*100;
			}
		}
		return $ret;
	}

	public function getOppositenessWith(User $other){
		if($this->getLypoSignature() && $other->getLypoSignature()){
			$own = new LypoSignature($this->getLypoSignature());
			$other = new LypoSignature($other->getLypoSignature());
			return $own->getOppositePercentageFor($other);
		}
		return 0;
	}

	public function getPerfectOppositesReactionCount(LypoStatement $debate){
		//Eerst perfect opposite ids ophalen
		$ids = $this->getPerfectOppositesIds();
		if($ids){
			$c = new Criteria();
			$c->add(ReactionPeer::USER_ID,$ids,Criteria::IN);
			$c->add(ReactionPeer::STATEMENT_ID,$debate->getId());
			return ReactionPeer::doCount($c);
		}
		return 0;
	}

	public function addPerfectOpposite($opposite_id=null){
		if($opposite_id){
			if((int)$opposite_id == $this->getId()) throw new sfException('You cannot add yourself as your own perfect opposite!');
			$opposite = UserPeer::retrieveByPK($opposite_id);
			if(!$opposite) throw new sfException('Opposite not found!');

			$c = new Criteria();
			$c->add(PerfectOppositePeer::USER_ID,$this->getId());
			$c->add(PerfectOppositePeer::OPPOSITE_ID,$opposite->getId());
			$existing = PerfectOppositePeer::doCount($c);
			if($existing > 0) throw new sfException('User is already a perfect opposite!');

			$po = new PerfectOpposite();
			$po->setUserId($this->getId());
			$po->setOppositeId($opposite->getId());
			$po->save();
			return true;
		}else{
			throw new sfException("No opposite id!");
		}
	}

	public function removePerfectOpposite($opposite_id=null){
		if($opposite_id){
			try {
				$opposite = UserPeer::retrieveByPK($opposite_id);
				if(!$opposite) throw new sfException('Opposite not found!');

				$c = new Criteria();
				$c->add(PerfectOppositePeer::USER_ID,$this->getId());
				$c->add(PerfectOppositePeer::OPPOSITE_ID,$opposite->getId());
				PerfectOppositePeer::doDelete($c);
			} catch (sfException $e){
				throw $e;
			}
		}else{
			throw new sfException("No opposite id!");
		}
	}


	public function getMyRespectedUsers(){
		$c = new Criteria();
		$c->add(ReactionRespectPeer::USER_ID,$this->getId());
		$c->addJoin(ReactionPeer::ID,ReactionRespectPeer::REACTION_ID);
		$c->addJoin(UserPeer::ID,ReactionPeer::USER_ID);
		$c->addAsColumn('numrespects','COUNT(*)');
		$c->addGroupByColumn(UserPeer::ID);
		$rs = UserPeer::doSelectRS($c);

		$respects = array();
		$results = array();
		
		$cls = UserPeer::getOMClass();
		$cls = sfPropel::import($cls);
		while($rs->next()) {
			$obj = new $cls();
			$offset = $obj->hydrate($rs);
			$respects[$obj->getId()]=$rs->getInt($offset);
			$results[] = $obj;
		}
		$data = array('users' => $results, 'respects' => $respects);
		return $data;
	}

	public function getNetworks(){
		$networks = array();
		$c = new Criteria();
		$c->addGroupByColumn(UserContainerPeer::CONTAINER_ID);
		$result = $this->getUserContainersJoinContainer($c);
		if($result){
			foreach($result as $user_container){
				/* var $user_container UserContainer */
				$networks[]=$user_container->getContainer()->getName();
			}
		}
		return $networks;
	}
	
	public function save($con = null){
		if(!$this->validateData()){
			throw new Exception("User invalid, not enough data given?");
		}
		parent::save($con);
	}
	
}
